﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;

namespace LoungeWare
{
    class MovieLoader : BackgroundWorker
    {
        #region Private member variables
        static ImdbServices.Imdb imdb = new ImdbServices.Imdb();
        private static object m_lock = new object();
        private string m_sPath;
        private string m_sFilename;

        #endregion

        #region Ctror / DoWork
        public MovieLoader(string sPath)
        {
            m_sPath = sPath;
            imdb.SearchResultsDownloaded +=
                new ImdbServices.Imdb.SearchResultsDownloadedEventHandler(SearchResultsDownloaded);
            imdb.MovieInfoDownloaded +=
                new ImdbServices.Imdb.MovieInfoDownloadedEventHandler(MovieInfoDownloadedEventHandler);
            imdb.Exception += new ImdbServices.Imdb.ExceptionEventHandler(imdb_Exception);
        }

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            int nCount = 0;
            string[] aFiles = System.IO.Directory.GetFiles(m_sPath);
            foreach (string sFilename in aFiles)
            {
                System.IO.FileInfo fiMovie = new FileInfo(sFilename);

                if (fiMovie.Extension.ToUpper() == ".AVI")
                {
                    string sMovie = fiMovie.Name.Substring(0, fiMovie.Name.LastIndexOf('.'));
                    Monitor.Enter(m_lock);
                    MovieExplorer.Instance.SetStatusLabel("Processing " + sMovie + "...");
                    MovieExplorer.Instance.SetStatusProgress(++nCount, aFiles.Count());
                    m_sFilename = fiMovie.Name;
                    m_sPath = sFilename;
                    imdb.SearchMovieAsync(sMovie, false, false);

                    //Wait for pulse before processing next movie...
                    System.Threading.Monitor.Wait(m_lock);
                    Monitor.Exit(m_lock);
                }
            }
            base.OnDoWork(e);
        }

        #endregion

        #region IMDB events
		private void SearchResultsDownloaded(ImdbServices.MoviesResultset M)
        {
            if (M != null)
            {
                if (M.PopularTitles.Count > 0)
                {
                    foreach (ImdbServices.Movie Movie in M.PopularTitles)
                    {
                        imdb.GetMovieInfoAsync(Movie.ImdbID, false);
                        return;
                    }
                }
                if (M.ExactMatches.Count > 0)
                {
                    foreach (ImdbServices.Movie Movie in M.ExactMatches)
                    {
                        imdb.GetMovieInfoAsync(Movie.ImdbID, false);
                        return;
                    }
                }
                if (M.PartialMatches.Count > 0)
                {
                    foreach (ImdbServices.Movie Movie in M.PartialMatches)
                    {
                        imdb.GetMovieInfoAsync(Movie.ImdbID, false);
                        return;
                    }
                }
            }

            //If no matches, move on
            Monitor.Enter(m_lock);
            System.Threading.Monitor.Pulse(m_lock);
            Monitor.Exit(m_lock);
        }

        private void MovieInfoDownloadedEventHandler(ImdbServices.Movie Movie)
        {
            ListViewItem item = new ListViewItem(new[] { Movie.Title, Movie.Rating.ToString(), Movie.Description, m_sFilename });
            item.Tag = m_sPath;

            Monitor.Enter(m_lock);
            //Add item to the list
            MovieExplorer.Instance.AddList(item); 
            //Move on to next item
            System.Threading.Monitor.Pulse(m_lock);
            Monitor.Exit(m_lock);
        }

        void imdb_Exception(Exception ex)
        {
            //eat it and move on
            Monitor.Enter(m_lock);
            System.Threading.Monitor.Pulse(m_lock);
            Monitor.Exit(m_lock);
        }

	    #endregion    
    }
}
